import React, { useState, useRef, useEffect } from 'react';
import {
    View,
    Text,
    StyleSheet,
    TouchableOpacity,
    Platform,
    PermissionsAndroid,
    ActivityIndicator,
    Dimensions,
} from 'react-native';
import { Camera } from 'expo-camera';
import { Video } from 'expo-av';
import * as ImagePicker from 'expo-image-picker';
import * as FileSystem from 'expo-file-system';
import { MaterialIcons } from '@expo/vector-icons';

interface VideoRecorderProps {
    onVideoRecorded: (videoUri: string) => void;
    maxDuration?: number;
    maxSize?: number;
    quality?: 'low' | 'medium' | 'high';
}

const VideoRecorder: React.FC<VideoRecorderProps> = ({
    onVideoRecorded,
    maxDuration = 30, // default max 30 seconds
    maxSize = 10 * 1024 * 1024, // default max 10MB
    quality = 'medium',
}) => {
    const [hasPermission, setHasPermission] = useState<boolean | null>(null);
    const [isRecording, setIsRecording] = useState(false);
    const [videoUri, setVideoUri] = useState<string | null>(null);
    const [isProcessing, setIsProcessing] = useState(false);
    const [countdown, setCountdown] = useState(maxDuration);
    const [isFrontCamera, setIsFrontCamera] = useState(false);
    const [cameraType, setCameraType] = useState(Camera.Constants.Type.back);

    const cameraRef = useRef<Camera>(null);
    const countdownTimerRef = useRef<NodeJS.Timeout | null>(null);

    useEffect(() => {
        (async () => {
            if (Platform.OS === 'android') {
                const { status } = await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.CAMERA,
                    {
                        title: "Camera Permission",
                        message: "This app needs access to your camera to record videos",
                        buttonNeutral: "Ask Me Later",
                        buttonNegative: "Cancel",
                        buttonPositive: "OK"
                    }
                );
                setHasPermission(status === PermissionsAndroid.RESULTS.GRANTED);

                const audioStatus = await PermissionsAndroid.request(
                    PermissionsAndroid.PERMISSIONS.RECORD_AUDIO,
                    {
                        title: "Microphone Permission",
                        message: "This app needs access to your microphone to record videos with audio",
                        buttonNeutral: "Ask Me Later",
                        buttonNegative: "Cancel",
                        buttonPositive: "OK"
                    }
                );
                if (audioStatus !== PermissionsAndroid.RESULTS.GRANTED) {
                    console.warn('Audio recording permissions not granted');
                }
            } else {
                const { status } = await Camera.requestPermissionsAsync();
                setHasPermission(status === 'granted');
            }
        })();

        return () => {
            if (countdownTimerRef.current) {
                clearInterval(countdownTimerRef.current);
            }
        };
    }, []);

    const startRecording = async () => {
        if (cameraRef.current && !isRecording && !videoUri) {
            setIsRecording(true);
            setCountdown(maxDuration);

            countdownTimerRef.current = setInterval(() => {
                setCountdown((prev) => {
                    if (prev <= 1) {
                        stopRecording();
                        return 0;
                    }
                    return prev - 1;
                });
            }, 1000);

            const qualityValue = Platform.OS === 'ios'
                ? (quality === 'high' ? Camera.Constants.VideoQuality['1080p'] :
                    quality === 'medium' ? Camera.Constants.VideoQuality['720p'] :
                        Camera.Constants.VideoQuality['480p'])
                : (quality === 'high' ? Camera.Constants.VideoQuality['high'] :
                    quality === 'medium' ? Camera.Constants.VideoQuality['medium'] :
                        Camera.Constants.VideoQuality['low']);

            try {
                const videoOptions = {
                    maxDuration,
                    quality: qualityValue,
                    mute: false,
                };

                const video = await cameraRef.current.recordAsync(videoOptions);
                setVideoUri(video.uri);

                // Process the video (compression, etc)
                await processVideo(video.uri);
            } catch (error) {
                console.error('Error recording video:', error);
                setIsRecording(false);
                if (countdownTimerRef.current) {
                    clearInterval(countdownTimerRef.current);
                }
            }
        }
    };

    const stopRecording = async () => {
        if (cameraRef.current && isRecording) {
            cameraRef.current.stopRecording();
            setIsRecording(false);

            if (countdownTimerRef.current) {
                clearInterval(countdownTimerRef.current);
            }
        }
    };

    const processVideo = async (uri: string) => {
        setIsProcessing(true);

        try {
            // Get file info
            const fileInfo = await FileSystem.getInfoAsync(uri);

            // Check if the video needs to be compressed
            if (fileInfo.size > maxSize) {
                // For actual compression we would use video-compressor library or native methods
                // This is a mock implementation that just copies the file to simulate processing
                console.log('Video would be compressed from', fileInfo.size, 'to target size', maxSize);

                // In a real implementation, use appropriate video compression library
                // For now, we'll just use the original file
                const processedUri = uri;

                // Update the state with processed video URI
                setVideoUri(processedUri);
                onVideoRecorded(processedUri);
            } else {
                // No need to compress
                onVideoRecorded(uri);
            }
        } catch (error) {
            console.error('Error processing video:', error);
        } finally {
            setIsProcessing(false);
        }
    };

    const retakeVideo = () => {
        setVideoUri(null);
        setCountdown(maxDuration);
    };

    const pickVideoFromLibrary = async () => {
        try {
            const result = await ImagePicker.launchImageLibraryAsync({
                mediaTypes: ImagePicker.MediaTypeOptions.Videos,
                allowsEditing: true,
                quality: 1,
                videoMaxDuration: maxDuration,
            });

            if (!result.canceled && result.assets && result.assets.length > 0) {
                const selectedVideo = result.assets[0];
                setVideoUri(selectedVideo.uri);

                // Process the selected video
                await processVideo(selectedVideo.uri);
            }
        } catch (error) {
            console.error('Error picking video from gallery:', error);
        }
    };

    const toggleCameraType = () => {
        setCameraType(
            cameraType === Camera.Constants.Type.back
                ? Camera.Constants.Type.front
                : Camera.Constants.Type.back
        );
        setIsFrontCamera(!isFrontCamera);
    };

    if (hasPermission === null) {
        return <View style={styles.container}><Text>Requesting camera permission...</Text></View>;
    }

    if (hasPermission === false) {
        return <View style={styles.container}><Text>No access to camera. Please enable camera permissions.</Text></View>;
    }

    return (
        <View style={styles.container}>
            {videoUri ? (
                <View style={styles.previewContainer}>
                    <Video
                        source={{ uri: videoUri }}
                        rate={1.0}
                        volume={1.0}
                        isMuted={false}
                        resizeMode="cover"
                        shouldPlay={true}
                        isLooping={true}
                        style={styles.preview}
                        useNativeControls
                    />

                    <View style={styles.buttonRow}>
                        <TouchableOpacity onPress={retakeVideo} style={styles.button}>
                            <MaterialIcons name="replay" size={24} color="white" />
                            <Text style={styles.buttonText}>Retake</Text>
                        </TouchableOpacity>

                        {isProcessing ? (
                            <View style={styles.processingContainer}>
                                <ActivityIndicator size="small" color="#ffffff" />
                                <Text style={styles.processingText}>Processing video...</Text>
                            </View>
                        ) : null}
                    </View>
                </View>
            ) : (
                <View style={styles.cameraContainer}>
                    <Camera
                        ref={cameraRef}
                        style={styles.camera}
                        type={cameraType}
                        ratio="16:9"
                    >
                        <View style={styles.controlsContainer}>
                            <View style={styles.topControls}>
                                <TouchableOpacity
                                    style={styles.cameraToggle}
                                    onPress={toggleCameraType}
                                >
                                    <MaterialIcons name="flip-camera-ios" size={28} color="white" />
                                </TouchableOpacity>

                                {isRecording && (
                                    <View style={styles.countdownContainer}>
                                        <Text style={styles.countdownText}>{countdown}s</Text>
                                    </View>
                                )}
                            </View>

                            <View style={styles.bottomControls}>
                                <TouchableOpacity
                                    onPress={pickVideoFromLibrary}
                                    style={styles.galleryButton}
                                >
                                    <MaterialIcons name="photo-library" size={28} color="white" />
                                </TouchableOpacity>

                                <TouchableOpacity
                                    onPress={isRecording ? stopRecording : startRecording}
                                    style={[
                                        styles.recordButton,
                                        isRecording ? styles.stopRecordButton : {}
                                    ]}
                                >
                                    {isRecording ? (
                                        <View style={styles.stopIcon} />
                                    ) : (
                                        <View style={styles.recordIcon} />
                                    )}
                                </TouchableOpacity>

                                <View style={styles.spacer} />
                            </View>
                        </View>
                    </Camera>
                </View>
            )}
        </View>
    );
};

const { width, height } = Dimensions.get('window');

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: '#000',
    },
    cameraContainer: {
        flex: 1,
        overflow: 'hidden',
        borderRadius: 12,
    },
    camera: {
        flex: 1,
    },
    controlsContainer: {
        flex: 1,
        backgroundColor: 'transparent',
        flexDirection: 'column',
        justifyContent: 'space-between',
        padding: 20,
    },
    topControls: {
        flexDirection: 'row',
        justifyContent: 'space-between',
        alignItems: 'center',
    },
    bottomControls: {
        flexDirection: 'row',
        justifyContent: 'space-around',
        alignItems: 'center',
        marginBottom: 20,
    },
    recordButton: {
        borderWidth: 3,
        borderColor: 'white',
        backgroundColor: 'rgba(255, 0, 0, 0.4)',
        borderRadius: 35,
        height: 70,
        width: 70,
        justifyContent: 'center',
        alignItems: 'center',
    },
    stopRecordButton: {
        backgroundColor: 'rgba(255, 0, 0, 0.7)',
    },
    recordIcon: {
        backgroundColor: 'red',
        width: 54,
        height: 54,
        borderRadius: 27,
    },
    stopIcon: {
        backgroundColor: 'white',
        width: 24,
        height: 24,
        borderRadius: 3,
    },
    galleryButton: {
        padding: 10,
    },
    spacer: {
        width: 50,
    },
    cameraToggle: {
        padding: 10,
    },
    countdownContainer: {
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
        paddingHorizontal: 10,
        paddingVertical: 5,
        borderRadius: 15,
    },
    countdownText: {
        color: 'white',
        fontWeight: 'bold',
        fontSize: 16,
    },
    previewContainer: {
        flex: 1,
        borderRadius: 12,
        overflow: 'hidden',
    },
    preview: {
        flex: 1,
    },
    buttonRow: {
        position: 'absolute',
        bottom: 0,
        left: 0,
        right: 0,
        flexDirection: 'row',
        justifyContent: 'space-around',
        padding: 20,
        backgroundColor: 'rgba(0, 0, 0, 0.5)',
    },
    button: {
        backgroundColor: 'rgba(78, 78, 78, 0.8)',
        borderRadius: 20,
        padding: 10,
        paddingHorizontal: 20,
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
    },
    buttonText: {
        color: 'white',
        marginLeft: 5,
    },
    processingContainer: {
        flexDirection: 'row',
        alignItems: 'center',
        justifyContent: 'center',
        backgroundColor: 'rgba(0, 0, 0, 0.7)',
        borderRadius: 20,
        padding: 10,
        paddingHorizontal: 20,
    },
    processingText: {
        color: 'white',
        marginLeft: 10,
    }
});

export default VideoRecorder; 